﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;

using vJine.Core.Base;
using vJine.Core.ORM;
using vJine.Lua.GUI;

namespace vJine.Lua.GUI.BLL {
    public class NodeDataHandle : NodeConfig {
        public NodeDataHandle() {
            this.init_node();
        }

        LuaContext Context { get; set; }
        NodeConfig runConfig { get; set; }
        NodeConfig nSpecTable { get; set; }
        NodeConfig nDataTable { get; set; }
        void init_node() {
            this.name = "save_data";
            this.alias = "保存数据";

            this.init_config("connString", "连接字符", "").p = true;
            this.init_config("user", "用户ID", "user").p = true;
            this.init_config("pwd", "用户密码", "password").p = true;
            //
            this.nSpecTable = this.init_config("spec_table", "指标表名", "spec_table");
            this.nSpecTable.p = true;
            this.nDataTable = this.init_config("data_table", "数据表名", "data_table");
            this.nDataTable.p = true;
            //
            this.OnInit = (LuaContext context, NodeConfig runConfig) => {
                this.Context = context;
                this.runConfig = runConfig;
                this.load_spec(runConfig);
                return null;
            };

            this.OnSet = (NodeConfig nConfig) => {
                if (nConfig.name == "SPEC") {
                    string spec_name = nConfig;
                    
                } else if (!nConfig.data) {
                    return null;
                }

                this.check_item_spec(this.Context, nConfig);
                return null;
            };

            this.OnInvoke = (NodeConfig nConfig) => {
                string result = this.check_data_spec(this.runConfig);

                this.save_result(this.Context, this.runConfig);
                return null;
            };
        }

        NodeConfig nSpecConfig = null;
        SpecCollection Specs = new SpecCollection();
        void load_spec(NodeConfig runConfig) {
            this.Specs.Clear();

            if (runConfig.configs != null) {
                for (int i = 0, len = runConfig.configs.Count; i < len; i++) {
                    NodeConfig nConfig_i = runConfig.configs[i];
                    if (nConfig_i.name == "SPEC") {
                        this.nSpecConfig = nConfig_i;
                    }
                }
            }

            if (this.nSpecConfig == null) {
                throw new vJine.Core.CoreException("未找到【指标配置】项");
            }
            string spec_name = this.nSpecConfig;

            string spec_table = this.nSpecTable;
            if (string.IsNullOrEmpty(spec_table)) {
                throw new vJine.Core.CoreException("未设置【指标数据表】项");
            }
            //
            List<ListItem> specs = new List<ListItem>();
            Spec spec_A = new Spec() { name = "SPEC-A" };
            spec_A.Add(new SpecItem() { name = "A", min = 1, max = 5 });
            this.Specs.Add(spec_A);
            specs.Add(new ListItem() { Checked = spec_name == spec_A.name, Value = spec_A.name });
            Spec spec_B = new Spec() { name = "SPEC-B" };
            spec_B.Add(new SpecItem() { name = "A", min = 1, max = 6 });
            this.Specs.Add(spec_B);
            specs.Add(new ListItem() { Checked = spec_name == spec_B.name, Value = spec_B.name });
            Spec spec_C = new Spec() { name = "SPEC-C" };
            spec_C.Add(new SpecItem() { name = "A", min = 1, max = 7 });
            this.Specs.Add(spec_C);
            specs.Add(new ListItem() { Checked = spec_name == spec_C.name, Value = spec_C.name });
            Spec spec_D = new Spec() { name = "SPEC-D" };
            spec_D.Add(new SpecItem() { name = "A", min = 1, max = 8 });
            this.Specs.Add(spec_D);
            specs.Add(new ListItem() { Checked = spec_name == spec_D.name, Value = spec_D.name });
            Spec spec_E = new Spec() { name = "SPEC-E" };
            spec_E.Add(new SpecItem() { name = "A", min = 1, max = 9 });
            this.Specs.Add(spec_E);
            specs.Add(new ListItem() { Checked = spec_name == spec_D.name, Value = spec_E.name });

            this.nSpecConfig.value = null;
            this.nSpecConfig.multi = false;
            this.nSpecConfig.list = specs;
        }

        void check_item_spec(LuaContext context, NodeConfig nConfig) {
            Spec spec = this.Specs.GetSpecByName(this.nSpecConfig);
            if (spec == null) {
                return;
            }
            string result = spec.CheckItem(nConfig.param, nConfig);
            if (string.IsNullOrEmpty(result)) {
                return;
            }

            context.exec("on_warn", result);
        }

        /// <summary>
        /// 未找到Spec返回null,成功返回空字符，失败返回原因
        /// </summary>
        /// <param name="runConfig"></param>
        /// <returns></returns>
        string check_data_spec(NodeConfig runConfig) {
            return "";
        }

        void save_result(LuaContext context, NodeConfig runConfig) {

        }

        public class SpecCollection : CollectionBase<Spec> {
            public Spec GetSpecByName(string name) {
                for (int i = 0, len = this.Count; i < len; i++) {
                    Spec spec_i = this[i];
                    if (spec_i.name == name) {
                        return spec_i;
                    }
                }

                return null;
            }
        }
        
        public class Spec : CollectionBase<SpecItem> {

            public string name { get; set; }
            public bool active { get; set; }
            public string remark { get; set; }

            public DateTime CreateTime { get; set; }
            public DateTime UpdateTime { get; set; }

            /// <summary>
            /// 未找到规格返回null，合格返回空字符，不合格返回不合格原因
            /// </summary>
            /// <param name="name">规格项名称</param>
            /// <param name="value">数据项数值</param>
            /// <returns></returns>
            public string CheckItem(string name, NodeConfig value) {
                SpecItem si = null;
                for (int i = 0, len = this.Count; i < len; i++) {
                    SpecItem specItem_i = this[i];
                    if (specItem_i.name == name) {
                        si = specItem_i; break;
                    }
                }

                if (si == null) {
                    return null;
                }
                if (si.min != null && value < si.min) {
                    return string.Format("{0}:{1} < {2}", name, (double)value, si.min);
                } else if (si.max != null && value > si.max) {
                    return string.Format("{0}:{1} > {2}", name, (double)value, si.max);
                } else {
                    return "";
                }
            }
        }

        public class SpecItem {
            public string name { get; set; }

            public double? min { get; set; }
            public double? set { get; set; }
            public double? max { get; set; }

            public string remark { get; set; }

            public DateTime CreateTime { get; set; }
            public DateTime UpdateTime { get; set; }
        }
    }
}
